Harden Phase 8's rebase fence and state the merge-authorization precedence rule - #119
Conversation
…dence rule The post-rebase verification ran the test command alone, so a required check that also runs a linter or static analysis survived the force-push and was rediscovered from CI minutes later. It now runs the same verification set Phase 3 runs. The bare --force-with-lease has three unrelated causes that share one '(stale info)' rejection — a restricted fetch refspec, an abbreviated SHA, and a genuine concurrent push. Only the third justifies backing off, so the fence now reads a full 40-character lease value from the remote at push time and the disambiguation rule is written down. Phase 8 also gains an explicit precedence rule: a run-level merge pre-authorization conveys permission, not validation, so it does not satisfy Phase 4's anchor gate on an UNVERIFIED PR. Closes #115 Closes #117 Closes #118 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-review rubricScored adversarially against the diff and command output, not judgment. Two Universal rubric
Repo-specific rubric
Findings
PR body (fixed during this review, not left as a finding) — the retrofit note Merge statusWithheld. Terminal state: open, CI green, self-review posted, awaiting a human able to run This review comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). |
|
@copilot please fix the merge conflicts in this pull request. |
|
@copilot please fix the merge conflicts in this pull request. |
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Merge conflicts resolved in 26b149f. Both |
The entry was written on the day the PR was opened and dated 2026-08-16, but the PR did not merge that day. Re-date it to the day the branch was finalized so the finding does not carry a ship date that never happened.
Follow-up review — merge-conflict resolution and anchor re-confirmationThe self-review posted earlier on this PR was scored against head External-anchor status — resolvedCI on Locally re-confirmed on the same tree, with executed counts read rather than exit
Review of
|
Summary
Three Phase 8 defects are corrected in
create-dev-loop.md. All three werereported from generated instances or prior self-audits, and all three live in
the same neighbourhood of the template — the merge phase and its "Branch is
behind main" Edge cases entry — so they are batched as one coherent change.
verified with
{{TEST_CMD}}alone and then force-pushed on the strength ofthat single result. Where a repository's required checks also run a formatter,
linter or static analysis, a branch could be pushed still-red and the failure
rediscovered from CI minutes later. The fence now runs the same verification
set Phase 3 runs (
{{COMPILE_CMD}},{{TEST_CMD}},{{#if LINT_CMD}}), andan accompanying paragraph states that where the repository's required checks
exceed that set, those must be run too.
(stale info)is disambiguated (Phase 8's bare --force-with-lease has three failure causes that share one '(stale info)' message #117). A bare--force-with-leaseneeds amaintained remote-tracking ref, which a restricted clone does not have; the
explicit
--force-with-lease=<branch>:<sha>form fixes that but rejects anabbreviated SHA with the same message. Three unrelated causes — a restricted
fetch refspec, an abbreviated SHA, and a genuine concurrent push — therefore
read identically, and only the third justifies backing off. The fence now
reads a full 40-character lease value from the remote at push time via
git ls-remote, and the disambiguation rule (plus a prohibition on fallingback to plain
--force) is written down next to it.dispatches each independently re-derived the answer to the same question:
when a run carries standing merge pre-authorization but Phase 4 has marked the
PR UNVERIFIED, which wins? A paragraph adjacent to the existing codeowner
exception now states that pre-authorization conveys permission rather than
evidence, and that the codeowner exception is retrospective by construction —
so a flag passed before the PR existed does not satisfy it.
Three substitution-table rows are updated so the placeholder guidance stays
accurate now that
COMPILE_CMDandLINT_CMDappear in two fences rather thanone, and the no-build-system paragraph's reference to the fence's "re-run tests"
step is reworded to match its new wording.
Retrofit note
Per
CLAUDE.md's "Promoting a rule into the template" section: all three rulesare template-wide, so every generated skill that predates this change will
keep carrying the old wording until its next regeneration. Retrofit passes are
likely needed on any existing
<slug>-dev-loopskill, and are not opened here —this dispatch is path-restricted to this repository's own checkout and cannot
reach the other skill repositories. Only the person running those skills can see
which ones exist. Two are already known to need it by name:
medieval-factions-dev-loop— the reporting instance for both Phase 8's rebase fence force-pushes on TEST_CMD alone, so a lint-gated required check survives it #115 and Phase 8's bare --force-with-lease has three failure causes that share one '(stale info)' message #117.Per Phase 8's bare --force-with-lease has three failure causes that share one '(stale info)' message #117 its
(stale info)half was already fixed locally; per Phase 8's rebase fence force-pushes on TEST_CMD alone, so a lint-gated required check survives it #115 itsgrooming step's verification line still names the test command alone.
create-dev-loop-dev-loop— this repository's own loop skill, last generatedfrom template
335eef0, which predates all three rules.Research grounding
Per
CLAUDE.md's "Grounding work in research":external signal is unreliable, confidence: high). Both defects degrade the
external anchor into something weaker than it appears. §1's existing
Implementations entry for PR Apply consolidated template-rule backlog (#36, #39–#51) #54 already records the neighbouring rule that
"green CI is not verification when CI's scope excludes the changed files";
verifying a rebase with a subset of the required checks is the same failure in
the merge phase, and treating a merge flag as a substitute for a validation
result replaces the anchor with permission. An Implementations entry for
this PR has been added under §1.
defect is plain Git behaviour — an ambiguous rejection message with three
causes — rather than a design decision about agent behaviour. Stating this
explicitly is preferred here over stretching a finding to cover it.
Test plan
python3 scripts/check_docs.py→Doc consistency check passed.python3 -m pytest tests/→ 13 passeddoc-consistencygreen on the PR head{{COMPILE_CMD}}and{{LINT_CMD}}arenewly used in the Phase 8 fence and both already carry Step 4 rows
diff, only edited within
stays 1:1 without modification
create-dev-loop.mdchecked out fromorigin/main, the fence readsre-run tests/{{TEST_CMD}}/ baregit push --force-with-leaseandno precedence paragraph is present; with the fix restored, all three are.
scripts/check_docs.pypasses in both states, which is the point of[self-audit] The repo's own validation anchor is structurally unrunnable in a headless dispatch, so template changes can never merge autonomously #109 — CI cannot observe this class of defect.
a manual
/create-dev-looprun against a real target repository. That isstructurally unrunnable in a headless dispatch (see [self-audit] The repo's own validation anchor is structurally unrunnable in a headless dispatch, so template changes can never merge autonomously #109), and this PR
changes
create-dev-loop.md, which is anchor-relevant. Per Phase 4'sgate the PR is therefore handed to a human rather than auto-merged, and
per the very precedence rule this PR adds, the standing merge
authorization carried by this run does not override that.
Deferred this cycle
Recorded for auditability, per Phase 1's skip-reason rule:
CLAUDE.mdisagent-loaded configuration, which Phase 1 classifies as requiring explicit,
separate authorization rather than a mid-cycle edit.
among four offered remedies, not an implementable defect.
.worktrees/survives gardener'sgit clean -fdx) —answering it requires reading
Stephenson-Software/gardener's refresh path,and reads outside this dispatch's own checkout remain unavailable. Guessing
would put an unverified claim into the template.
defect, but it lives in Phase 4 rather than Phase 8 and would have broken this
PR's localization coherence. It is the natural first pick for the next cycle.
Its correctness was incidentally re-confirmed while reviewing this PR: the
checkout form was used for the empirical revert above precisely because the
fix was already committed.
Closes #115
Closes #117
Closes #118
This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).